/**
 * Displays OpenCV video on framebuffer.
 * Compile with
 * g++ -o fbwrite_video -lopencv_core -lopencv_highgui -lopencv_imgproc fbwrite_video.cpp
 */

#include <iostream>
#include <opencv2/opencv.hpp>
#include <fstream>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <fcntl.h>

__u32 line_length;

void get_framebuffer_info(const char* framebuffer_device_path) {
    struct fb_var_screeninfo screen_info;
    struct fb_fix_screeninfo sfi;
    int fd = -1;

    fd = open(framebuffer_device_path, O_RDWR);
    ioctl(fd, FBIOGET_VSCREENINFO, &screen_info);
    ioctl(fd, FBIOGET_FSCREENINFO, &sfi);
    line_length = sfi.line_length;

    printf("%dx%d %d\n", screen_info.xres, screen_info.yres, screen_info.bits_per_pixel);
};

int main(int, char**) {
    get_framebuffer_info("/dev/fb0");
    cv::VideoCapture cap(0);
    std::ofstream ofs("/dev/fb0");

    cv::Mat frame;
    while (true) {
	    cap >> frame;

	    cv::Size2f frame_size = frame.size();
	    cv::cvtColor(frame, frame, CV_BGR2BGRA);
	    for (int y = 0; y < frame_size.height ; y++) {
		    ofs.seekp(y*line_length);
		    ofs.write(reinterpret_cast<char*>(frame.ptr(y)), frame_size.width*4);
	    }
	    ofs.flush();
	    usleep(1000*40);
    }
}

